package com.dhy.payutil.wechat;

import android.content.Context;
import android.content.pm.PackageInfo;
import android.content.pm.PackageManager;
import android.util.Log;
import android.widget.Toast;

import com.dhy.payutil.R;
import com.tencent.mm.sdk.modelpay.PayReq;
import com.tencent.mm.sdk.openapi.IWXAPI;
import com.tencent.mm.sdk.openapi.WXAPIFactory;

import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
import java.util.Random;

/**
 * You need set wechat_pay_app_id, wechat_pay_mch_id, wechat_pay_api_key in string file
 */
public class WechatPayHelper {
	private final IWXAPI msgApi;
	protected Context context;
	private PayReq req;
	final String APP_ID;
	/**
	 * 商户号
	 */
	final String MCH_ID;
	/**
	 * API密钥，在商户平台设置
	 */
	final String API_KEY;

	public WechatPayHelper(Context context) {
		this.context = context;
		APP_ID = context.getString(R.string.wechat_pay_app_id);
		MCH_ID = context.getString(R.string.wechat_pay_mch_id);
		API_KEY = context.getString(R.string.wechat_pay_api_key);
		msgApi = WXAPIFactory.createWXAPI(context, null);
	}

	private String genNonceStr() {
		return MD5.digest(String.valueOf(new Random().nextInt(10000)));
	}

	private long genTimeStamp() {
		return System.currentTimeMillis() / 1000;
	}

	private void initPayReq(String prepay_id) {
		req = new PayReq();
		req.appId = APP_ID;
		req.partnerId = MCH_ID;
		req.prepayId = prepay_id;
		req.packageValue = "Sign=WXPay";
		req.nonceStr = genNonceStr();
		req.timeStamp = String.valueOf(genTimeStamp());
		req.sign = sign();
	}

	private String sign() {
		Map<String, Object> map = new LinkedHashMap<>();
		map.put("appid", req.appId);
		map.put("noncestr", req.nonceStr);
		map.put("package", req.packageValue);
		map.put("partnerid", req.partnerId);
		map.put("prepayid", req.prepayId);
		map.put("timestamp", req.timeStamp);
		map.put("key", API_KEY);
		return MD5.digest(implode(map)).toUpperCase();
	}

	public boolean pay(String prepay_id) {
		if (!validSettings(APP_ID, MCH_ID, API_KEY)) return false;
		initPayReq(prepay_id);
		msgApi.registerApp(APP_ID);
		boolean sendReq = msgApi.sendReq(req);
		if (!sendReq) {
			String msg = msgApi.isWXAppInstalled() ? context.getString(R.string.wechat_pay_request_failed) : context.getString(R.string.wechat_pay_not_installed);
			Toast.makeText(context, msg, Toast.LENGTH_LONG).show();
		}
		return sendReq;
	}

	public void unregisterApp() {
		if (req != null) msgApi.unregisterApp();
	}

	private boolean validSettings(String... settings) {
		for (String s : settings) {
			if (s.length() < 3) {
				Toast.makeText(context, "You need set wechat_pay_app_id, wechat_pay_mch_id, wechat_pay_api_key in string file. See " + getClass().getSimpleName() + "'s DOC for more detail", Toast.LENGTH_LONG).show();
				return false;
			}
		}
		return true;
	}

	private String implode(Map<String, Object> map) {
		StringBuilder sb = new StringBuilder();
		for (String key : map.keySet()) {
			sb.append("&").append(key).append("=").append(map.get(key));
		}
		sb.deleteCharAt(0);
		return sb.toString();
	}

	public static void logAppSign(Context context, String tag) {
		String sign = null;
		PackageManager pm = context.getPackageManager();
		List<PackageInfo> apps = pm.getInstalledPackages(PackageManager.GET_SIGNATURES);
		String name = context.getPackageName();
		for (PackageInfo info : apps) {
			if (info.packageName.equals(name)) {
				sign = MD5.digest(info.signatures[0].toByteArray());
				break;
			}
		}
		Log.d(tag, "wechat pay app sign '" + sign + "'");
	}
}
